﻿# define _CRT_SECURE_NO_WARNINGS 1
1. 为什么使⽤⽂件？
如果没有⽂件，我们写的程序的数据是存储在电脑的内存中，如果程序退出，内存回收，数据就丢失
了，等再次运⾏程序，是看不到上次程序的数据的，如果要将数据进⾏持久化的保存，我们可以使⽤
⽂件。
2. 什么是⽂件？
磁盘上的⽂件是⽂件。
但是在程序设计中，我们⼀般谈的⽂件有两种：程序⽂件、数据⽂件（从⽂件功能的⻆度来分类
的）。
2.1 程序⽂件
程序⽂件包括源程序⽂件（后缀为.c）, ⽬标⽂件（windows环境后缀为.obj）, 可执⾏程序（windows
环境后缀为.exe）。
2.2 数据⽂件
⽂件的内容不⼀定是程序，⽽是程序运⾏时读写的数据，⽐如程序运⾏需要从中读取数据的⽂件，或
者输出内容的⽂件。
2.3 ⽂件名
⼀个⽂件要有⼀个唯⼀的⽂件标识，以便⽤⼾识别和引⽤。
⽂件名包含3部分：⽂件路径 + ⽂件名主⼲ + ⽂件后缀
例如： c : \code\test.txt
为了⽅便起⻅，⽂件标识常被称为⽂件名。
//#include <stdio.h>
//
//int main()
//{
//	int n = 0;
//	printf("%d\n", n);
//	scanf("%d", &n);
//	printf("%d\n", n);
//
//	return 0;
//}
//
//

根据数据的组织形式，数据⽂件被称为⽂本⽂件或者⼆进制⽂件。
数据在内存中以⼆进制的形式存储，如果不加转换的输出到外存，就是⼆进制⽂件。
如果要求在外存上以ASCII码的形式存储，则需要在存储前转换。以ASCII字符的形式存储的⽂件就是⽂
本⽂件。
⼀个数据在内存中是怎么存储的呢？
字符⼀律以ASCII形式存储，数值型数据既可以⽤ASCII形式存储，也可以使⽤⼆进制形式存储。
如有整数10000，如果以ASCII码的形式输出到磁盘，则磁盘中占⽤5个字节（每个字符⼀个字节），⽽
⼆进制形式输出，则在磁盘上只占4个字节
//#include <stdio.h>
//int main()
//{
//    int a = 10000;
//
//    FILE* pf = fopen("test.txt", "wb");
//    fwrite(&a, 4, 1, pf);//二进制的形式写到文件中
//    fclose(pf);
//    pf = NULL;
//
//    return 0;
//}
//
缓冲⽂件系统中，关键的概念是“⽂件类型指针”，简称“⽂件指针”。
每个被使⽤的⽂件都在内存中开辟了⼀个相应的⽂件信息区，⽤来存放⽂件的相关信息（如⽂件的名
字，⽂件状态及⽂件当前的位置等）。这些信息是保存在⼀个结构体变量中的。该结构体类型是由系
统声明的，取名FILE.

//#include <stdio.h>
//
//int main()
//{
//	FILE pf;
//	printf("hehe\n");
//	int n = 10;
//	scanf("%d", &n);
//
//	return 0;
//}
//
//
⽂件名
⼀个⽂件要有⼀个唯⼀的⽂件标识，以便⽤⼾识别和引⽤。
⽂件名包含3部分：⽂件路径 + ⽂件名主⼲ + ⽂件后缀
例如： c : \code\test.txt
为了⽅便起⻅，⽂件标识常被称为⽂件名。
#include <stdio.h>

//
//int main()
//{
//	//打开文件，为了写
//	//如果文件打来失败，会返回NULL
//	//
//	//FILE* pf = fopen("C:\\Users\\zpeng\\Desktop\\data.txt", "w");
//	//. 表示当前目录
//	//.. 表示上一级路径
//	//FILE* pf = fopen("./../../data.txt", "w");
//	FILE* pf = fopen("data.txt", "w");
//	if (pf == NULL)
//	{
//		perror("fopen");
//		return 1;
//	}
//	//写文件
//
//	//关闭文件
//	fclose(pf);
//	pf = NULL;
//
//	return 0;
//}

// 打开⽂件
FILE* fopen(const char* filename, const char* mode);
//关闭⽂件
int fclose(FILE* stream);
//int main()
//{
//	//打开文件
//	FILE* pf = fopen("data.txt", "w");
//	if (pf == NULL)
//	{
//		perror("fopen");
//		return 1;
//	}
//	//写文件
//	//fputc('a', pf);
//	//fputc('b', pf);
//	//fputc('c', pf);
//	//fputc('d', pf);
//
//	//int i = 0;
//	//for (i = 0; i < 26; i++)
//	//{
//	//	fputc('a'+i, pf);
//	//	//fputc('\n', pf);
//	//}
//
//	int i = 0;
//	for (i = 0; i < 26; i++)
//	{
//		fputc('a' + i, stdout);
//		//fputc('\n', pf);
//	}
//
//	//关闭文件
//	fclose(pf);
//	pf = NULL;
//
//	return 0;
//}
//

函数名 功能 适⽤于
fgetc 字符输⼊函数 所有输⼊流
fputc 字符输出函数 所有输出流
fgets ⽂本⾏输⼊函数 所有输⼊流
fputs ⽂本⾏输出函数 所有输出流
fscanf 格式化输⼊函数 所有输⼊流
fprintf 格式化输出函数 所有输出流
fread ⼆进制输⼊ ⽂件
fwrite ⼆进制输出 ⽂件
//
//int main()
//{
//	//打开文件
//	FILE* pf = fopen("data.txt", "r");
//	if (pf == NULL)
//	{
//		perror("fopen");
//		return 1;
//	}
//
//	//读文件
//	int ch = fgetc(pf);//a
//	printf("%c\n", ch);
//
//	ch = fgetc(pf);
//	printf("%c\n", ch);
//
//	ch = fgetc(pf);
//	printf("%c\n", ch);
//
//	ch = fgetc(pf);
//	printf("%c\n", ch);
//	//关闭文件
//	fclose(pf);
//	pf = NULL;
//
//	return 0;
//}

//写一个代码，完成将data1.txt文件的内容，拷贝一份生成data2.txt文件
//文件拷贝
//


//从data1.txt中读取数据
//写到data2.txt的文件中
//
//int main()
//{
//	FILE* pfread = fopen("data1.txt", "r");
//	if (pfread == NULL)
//	{
//		perror("fopen->data1.txt");
//		return 1;
//	}
//	FILE* pfwrite = fopen("data2.txt", "w");
//	if (pfwrite == NULL)
//	{
//		fclose(pfread);
//		pfread = NULL;
//		perror("fopen->data2.txt");
//		return 1;
//	}
//	//数据的读写（拷贝）
//	int ch = 0;
//	while ((ch = fgetc(pfread)) != EOF)
//	{
//		fputc(ch, pfwrite);
//	}
//
//
//	fclose(pfread);
//	fclose(pfwrite);
//
//	return 0;
//}
//

//int main()
//{
//	FILE* pf = fopen("data.txt", "w");
//	if (pf == NULL)
//	{
//		return 1;
//	}
//	//写文件 - 写一行
//	fputs("abcdef\n", pf);
//	fputs("abcdef\n", pf);
//	fputs("abcdef\n", pf);
//	fputs("abcdef\n", pf);
//
//
//	fclose(pf);
//	pf = NULL;
//	return 0;
//}
//
//int main()
//{
//	FILE* pf = fopen("data.txt", "r");
//	if (pf == NULL)
//	{
//		return 1;
//	}
//	//读取
//	char arr[20] = "xxxxxxxxxxxxxxx";
//	fgets(arr, 10, pf);
//
//
//	fclose(pf);
//	pf = NULL;
//	return 0;
//}

//
//int main()
//{
//	FILE* pf = fopen("data.txt", "r");
//	if (pf == NULL)
//	{
//		return 1;
//	}
//	//读取
//	char arr[20] = "xxxxxxxxxxxxxxx";
//	fgets(arr, 10, stdin);
//	fputs(arr, stdout);
//
//	fclose(pf);
//	pf = NULL;
//	return 0;
//}


//struct Stu
//{
//	char name[20];
//	int age;
//	float score;
//};
//
//int main()
//{
//	struct Stu s = { "zhangsan", 20, 90.5f };
//	FILE*pf = fopen("data.txt", "w");
//	if (pf == NULL)
//	{
//		return 1;
//	}
//	//写文件
//	fprintf(pf, "%s %d %.1f", s.name, s.age, s.score);
//
//	//
//	fclose(pf);
//	pf = NULL;
//
//	return 0;
//}

//struct Stu
//{
//	char name[20];
//	int age;
//	float score;
//};
//
//int main()
//{
//	struct Stu s = {0};
//	FILE* pf = fopen("data.txt", "r");
//	if (pf == NULL)
//	{
//		return 1;
//	}
//	//写读文件
//	fscanf(pf, "%s %d %f", s.name, &(s.age), &(s.score));
//
//	fprintf(stdout, "%s %d %.1f\n", s.name, s.age, s.score);
//	//
//	fclose(pf);
//	pf = NULL;
//
//	return 0;
//}


//fwrite

//struct Stu
//{
//	char name[20];
//	int age;
//	float score;
//};
//
//int main()
//{
//	struct Stu s = {"zhangsan", 20, 90.5};
//
//	FILE* pf = fopen("data.txt", "wb");
//	if (pf == NULL)
//	{
//		return 1;
//	}
//	//二进制的形式写文件
//	fwrite(&s, sizeof(s), 1, pf);
//	
//	fclose(pf);
//	pf = NULL;
//
//	return 0;
//}

struct Stu
{
	char name[20];
	int age;
	float score;
};

int main()
{
	struct Stu s = { 0 };

	FILE* pf = fopen("data.txt", "rb");
	if (pf == NULL)
	{
		return 1;
	}
	//二进制的形式读文件
	fread(&s, sizeof(s), 1, pf);

	printf("%s %d %.1f\n", s.name, s.age, s.score);

	fclose(pf);
	pf = NULL;

	return 0;
}
